﻿using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using System.Data.Entity.Repository.Filters;

namespace Testing.UnitTests
{
    //Run each unit test seperatly, because of the Filter is static...
    [TestClass]
    public class QueryableFilterTests
    {
        /// <summary>
        /// Expected Result: 1, because filter is enabled
        /// </summary>
        [TestMethod]
        public void IQueryable_FilterBasic_WithFilter()
        {
            RegisterableFilter filter = new RegisterableFilter
            {
                FilterInstance = new QueryableTestFilter(),
                ParameterBag = null
            };
            QueryableFilterManager.Register(filter);

            TestQueryable repo = new TestQueryable();

            List<TestEntity> entities = repo.GetTestEntities()
                .ToList();

            Assert.AreEqual(1, entities.Count());
        }

        /// <summary>
        /// Expected Result: 2 because filter is not enabled
        /// </summary>
        [TestMethod]
        public void IQueryable_FilterBasic_WithoutFilter()
        {
            //QueryableFilterManager.Register(new QueryableTestFilter());

            TestQueryable repo = new TestQueryable();

            List<TestEntity> entities = repo.GetTestEntities()
                .ToList();

            Assert.AreEqual(2, entities.Count());
        }

        /// <summary>
        /// This method demonstrates that the filter is static so first entities1 will count 2, other 2 will return 1 entities because the filter is enabled.
        /// </summary>
        [TestMethod]
        public void IQueryable_FilterBasic_DemoStaticFilter()
        {
            TestQueryable repo1 = new TestQueryable();

            List<TestEntity> entities1 = repo1.GetTestEntities()//2
                .ToList();

            RegisterableFilter filter = new RegisterableFilter
            {
                FilterInstance = new QueryableTestFilter(),
                ParameterBag = null
            };
            QueryableFilterManager.Register(filter);

            TestQueryable repo2 = new TestQueryable();

            List<TestEntity> entities2 = repo2.GetTestEntities()//1 (filter enabled)
                .ToList();

            TestQueryable repo3 = new TestQueryable();

            List<TestEntity> entities3 = repo3.GetTestEntities()//1 (filter still enabled)
                .ToList();
            
            Assert.AreEqual(4, (entities1.Count() + entities2.Count() + entities3.Count()));//total 4
        }

        /// <summary>
        /// This test demonstrates the FilterWith option that disables the QueryableTestFilter this should return a count of 2 because there are 2 entities and the filters are disabled.
        /// </summary>
        [TestMethod]
        public void IQueryable_FilterBasic_IgnoreRegisteredFilter()
        {
            RegisterableFilter filter = new RegisterableFilter
            {
                FilterInstance = new QueryableTestFilter(),
                ParameterBag = null
            };
            QueryableFilterManager.Register(filter);
            
            TestQueryable repo = new TestQueryable();

            List<TestEntity> entities = new TestQueryable().GetTestEntitiesWithoutFilter().ToList();

            IQueryable<TestEntity> result = entities.AsQueryable();
            result = result.FilterWith<IQueryableTestFilter, TestEntity>(new Type[] { typeof(QueryableTestFilter) });

            Assert.AreEqual(2, result.Count());
        }

        [TestCleanup]
        public void TestCleanup()
        {
            //QueryableFilterManager.UnRegister<QueryableTestFilter>();//entity
            //QueryableFilterManager.UnRegister(new List<object> { QueryableTestFilter });
            QueryableFilterManager.ClearFilters();
           // QueryableFilterManager.UnRegister<IQueryableTestFilter>();//interface

            //QueryableFilterManager.UnRegister(<T> Interface);
            //QueryableFilterManager.UnRegister(typeof(IQueryableFilter));
        }

    }
}
